package com.huatai.common.httputil;

/**
 * @program: ht-system
 * @description:
 * @author: songxiude
 * @create: 2023-04-25 15:36
 **/


import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonNode;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.BiConsumer;
import java.util.function.Function;
import javax.annotation.Nullable;
import okhttp3.Call;
import okhttp3.Request;

public class Exchange {
	private BiConsumer<Request, IOException> failedBiConsumer = (r, e) -> {
	};
	private final Call call;

	public Exchange onFailed(BiConsumer<Request, IOException> failConsumer) {
		this.failedBiConsumer = failConsumer;
		return this;
	}

	public <R> R onResponse(Function<ResponseSpec, R> func) {
		try {
			HttpResponse response = new HttpResponse(this.call.execute());
			Throwable var3 = null;

			Object var4;
			try {
				var4 = func.apply(response);
			} catch (Throwable var14) {
				var3 = var14;
				throw var14;
			} finally {
				if (response != null) {
					if (var3 != null) {
						try {
							response.close();
						} catch (Throwable var13) {
							var3.addSuppressed(var13);
						}
					} else {
						response.close();
					}
				}

			}

			return (R) var4;
		} catch (IOException var16) {
			throw Exceptions.unchecked(var16);
		}
	}

	@Nullable
	public <R> R onSuccess(Function<ResponseSpec, R> func) {
		try {
			HttpResponse response = new HttpResponse(this.call.execute());
			Throwable var3 = null;

			Object var4;
			try {
				var4 = func.apply(response);
			} catch (Throwable var14) {
				var3 = var14;
				throw var14;
			} finally {
				if (response != null) {
					if (var3 != null) {
						try {
							response.close();
						} catch (Throwable var13) {
							var3.addSuppressed(var13);
						}
					} else {
						response.close();
					}
				}

			}

			return (R) var4;
		} catch (IOException var16) {
			this.failedBiConsumer.accept(this.call.request(), var16);
			return null;
		}
	}

	@Nullable
	public <R> R onSuccessful(Function<ResponseSpec, R> func) {
		try {
			HttpResponse response = new HttpResponse(this.call.execute());
			Throwable var3 = null;

			Object var4;
			try {
				if (!response.isOk()) {
					this.failedBiConsumer.accept(this.call.request(), new IOException(response.toString()));
					return null;
				}

				var4 = func.apply(response);
			} catch (Throwable var15) {
				var3 = var15;
				throw var15;
			} finally {
				if (response != null) {
					if (var3 != null) {
						try {
							response.close();
						} catch (Throwable var14) {
							var3.addSuppressed(var14);
						}
					} else {
						response.close();
					}
				}

			}

			return (R) var4;
		} catch (IOException var17) {
			this.failedBiConsumer.accept(this.call.request(), var17);
			return null;
		}
	}

	public <R> Optional<R> onSuccessOpt(Function<ResponseSpec, R> func) {
		return Optional.ofNullable(this.onSuccess(func));
	}

	public <R> Optional<R> onSuccessfulOpt(Function<ResponseSpec, R> func) {
		return Optional.ofNullable(this.onSuccessful(func));
	}

	public String asString() {
		return (String)this.onResponse(ResponseSpec::asString);
	}

	public byte[] asBytes() {
		return (byte[])this.onResponse(ResponseSpec::asBytes);
	}

	public JsonNode asJsonNode() {
		return (JsonNode)this.onResponse(ResponseSpec::asJsonNode);
	}

	public <T> T asValue(Class<T> valueType) {
		return this.onResponse((responseSpec) -> {
			return responseSpec.asValue(valueType);
		});
	}

	public <T> T asValue(TypeReference<T> typeReference) {
		return this.onResponse((responseSpec) -> {
			return responseSpec.asValue(typeReference);
		});
	}

	public <T> List<T> asList(Class<T> valueType) {
		return (List)this.onResponse((responseSpec) -> {
			return responseSpec.asList(valueType);
		});
	}

	public <K, V> Map<K, V> asMap(Class<?> keyClass, Class<?> valueType) {
		return (Map)this.onResponse((responseSpec) -> {
			return responseSpec.asMap(keyClass, valueType);
		});
	}

	public <V> Map<String, V> asMap(Class<?> valueType) {
		return (Map)this.onResponse((responseSpec) -> {
			return responseSpec.asMap(valueType);
		});
	}

	public <T> T asDomValue(Class<T> valueType) {
		return this.onResponse((responseSpec) -> {
			return responseSpec.asDomValue(valueType);
		});
	}

	public <T> List<T> asDomList(Class<T> valueType) {
		return (List)this.onResponse((responseSpec) -> {
			return responseSpec.asDomList(valueType);
		});
	}

	public File toFile(File file) {
		return (File)this.onResponse((responseSpec) -> {
			return responseSpec.toFile(file);
		});
	}

	public Path toFile(Path path) {
		return (Path)this.onResponse((responseSpec) -> {
			return responseSpec.toFile(path);
		});
	}

	public Exchange(final Call call) {
		this.call = call;
	}
}

